
import java.io.*;
import java.net.*;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;

public class TCPServiceThread extends Thread {
	public static final String FinalString = "Bye";
	public static final String ACK = "ACK";
	private Integer nPut=0, nGet=0, nFilter=0, nResize=0;
	
	
	private Socket s;

	public ArrayList<Integer> vectorFisiere;
	public String extensie;
	
	public void setStat(Integer nPut, Integer nGet, Integer nFilter, Integer nResize) {
		this.nPut = nPut;
		this.nGet = nGet;
		this.nFilter = nFilter;
		this.nResize = nResize;
	}
	
	public TCPServiceThread(Socket s) {
		this.s = s;
		vectorFisiere = new ArrayList<Integer>();
	}
	
	public static String readFileAsString(String filePath) throws java.io.IOException{
        StringBuffer fileData = new StringBuffer(1000);
        BufferedReader reader = new BufferedReader(
                new FileReader(filePath));
        char[] buf = new char[1024];
        int numRead=0;
        while((numRead=reader.read(buf)) != -1){
            String readData = String.valueOf(buf, 0, numRead);
            fileData.append(readData);
            buf = new char[1024];
        }
        reader.close();
        return fileData.toString();
    }
	
	public void run() {
		int cnt = 0;

		try {
			PrintWriter out = new PrintWriter(this.s.getOutputStream(), true); 
			BufferedReader in = new BufferedReader(new InputStreamReader(this.s.getInputStream()));

			while (true) {
				String line = in.readLine();
				System.out.println("[TCPServiceThread-" + this.hashCode() + "] Received: " + line);
				
				String value = new String (line);
				
				String[] elemente = value.split(" ");
				
				if(elemente[0].equalsIgnoreCase("put"))
				{
					int poziton = value.indexOf(":");
					String numberDim = value.substring(poziton+1);
					
					System.out.println("Am numarul " + numberDim);
					
					int dimFisier = Integer.parseInt("" + numberDim.trim() + "");
					
					
					char [] bufFisier = new char [dimFisier];
					int dim = in.read(bufFisier);
					
					System.out.println("[TCPServiceThread-" + this.hashCode() + "] Received: " + bufFisier);
					
					// Sleep a bit to simulate the processing of a request.
					Thread.sleep(500);

					byte [] fisierByte = new  byte [bufFisier.length];
					
					for (int i = 0; i < bufFisier.length; i++) {
						  fisierByte[i] = (byte) bufFisier[i];
					 }

					
					System.out.println("Primesc date despre fisire " + bufFisier);
					
					
					//String receivedData = new String(packet.getData(), 0, packet.getLength());
					//System.out.println("[UDPServiceThread-" + this.hashCode() + "] Received: " + receivedData);
					
					// Simulate the processing of the request by sleeping a bit.
					
					 try
				     {
					      FileOutputStream fos = new FileOutputStream("Storage\\" + (vectorFisiere.size() + 1)  + elemente[1].substring(elemente[1].indexOf('.')));
					         
					      /*
					       * To write byte array to a file, use
					       * void write(byte[] bArray) method of Java FileOutputStream class.
					       *
					       * This method writes given byte array to a file.
					       */
					     
					       fos.write(fisierByte);
					     
					       vectorFisiere.add(vectorFisiere.size() + 1);
					      /*
					       * Close FileOutputStream using,
					       * void close() method of Java FileOutputStream class.
					       *
					       */
					     
					       fos.close();
					      
				     
				     }
				     catch(FileNotFoundException ex)
				     {
				    	 System.out.println("FileNotFoundException : " + ex);
				     }
				     catch(IOException ioe)
				     {
				    	 System.out.println("IOException : " + ioe);
				     }
					 
					try {
						Thread.sleep(500);
					} catch (Exception e) {}
					
					// Send back an answer.
					out.println(vectorFisiere.size());
					cnt++;

					
					this.s.close();
					break;
					
				}else{
					if(elemente[0].equalsIgnoreCase("get"))
					{
						String fisierDeTrimis = TCPServiceThread.readFileAsString("Storage/"+elemente[1]);
						
						System.out.println("Vreau sa trimit mai departe " + fisierDeTrimis);
						//out.println(fisierDeTrimis.length());
						//out.write(fisierDeTrimis.length());
						out.print(fisierDeTrimis);
						
						cnt++;

						
						this.s.close();
						break;
					}else
					{
						if(elemente[0].equalsIgnoreCase("filter"))
						{
							this.extensie = elemente[2].substring(elemente[2].indexOf('.'));
							
							//trebuie creat noul fisier
							byte [] fisierByte = new byte[1024];
							//scriu informatia in fisierul modificat
							 try
						     {
							      FileOutputStream fos = new FileOutputStream("Storage\\" + (vectorFisiere.size() + 1) + "." + this.extensie);
							     
							      /*
							       * To write byte array to a file, use
							       * void write(byte[] bArray) method of Java FileOutputStream class.
							       *
							       * This method writes given byte array to a file.
							       */
							     
							       fos.write(fisierByte);
							     
							       vectorFisiere.add(vectorFisiere.size() + 1);
							      /*
							       * Close FileOutputStream using,
							       * void close() method of Java FileOutputStream class.
							       *
							       */
							     
							       fos.close();
						     
						     }
						     catch(FileNotFoundException ex)
						     {
						    	 System.out.println("FileNotFoundException : " + ex);
						     }
						     catch(IOException ioe)
						     {
						    	 System.out.println("IOException : " + ioe);
						     }
							 
							try {
								Thread.sleep(500);
							} catch (Exception e) {}
							

							// Send back an answer.
							out.println(vectorFisiere.size());
							cnt++;

							
							this.s.close();
							break;
						}else
						{
							if(elemente[0].equalsIgnoreCase("resize"))
							{
								String lungimeResize = elemente[1];
								String latimeResize = elemente[2];
								this.extensie = elemente[3].substring(elemente[3].indexOf('.'));
								
								//trebuie creat noul fisier
								byte [] fisierByte = new byte[1024];
								
								try
							     {
								      FileOutputStream fos = new FileOutputStream("Storage\\" + (vectorFisiere.size() + 1) + "." + this.extensie);
								     
								      /*
								       * To write byte array to a file, use
								       * void write(byte[] bArray) method of Java FileOutputStream class.
								       *
								       * This method writes given byte array to a file.
								       */
								     
								       fos.write(fisierByte);
								     
								       vectorFisiere.add(vectorFisiere.size() + 1);
								      /*
								       * Close FileOutputStream using,
								       * void close() method of Java FileOutputStream class.
								       *
								       */
								     
								       fos.close();
							     
							     }
							     catch(FileNotFoundException ex)
							     {
							    	 System.out.println("FileNotFoundException : " + ex);
							     }
							     catch(IOException ioe)
							     {
							    	 System.out.println("IOException : " + ioe);
							     }
								 
								try {
									Thread.sleep(500);
								} catch (Exception e) {}
								

								// Send back an answer.
								out.println(vectorFisiere.size());
								cnt++;

								
								this.s.close();
								break;
							}
						}
					}
				}
				
			}
		} catch (Exception e) {
			System.err.println("TCPServiceThread-" + this.hashCode() + " exception: " + e);
			e.printStackTrace();
		}
	}
}
